"""
告警管理系统数据模型
定义告警规则、告警事件、通知配置等相关数据结构
"""
from datetime import datetime
from typing import List, Dict, Optional, Any, Union
from pydantic import BaseModel, Field
from enum import Enum


class AlertLevel(str, Enum):
    """告警级别枚举"""
    CRITICAL = "critical"      # 严重
    HIGH = "high"             # 高
    MEDIUM = "medium"         # 中等
    LOW = "low"              # 低
    INFO = "info"            # 信息


class AlertStatus(str, Enum):
    """告警状态枚举"""
    ACTIVE = "active"         # 活跃
    ACKNOWLEDGED = "acknowledged"  # 已确认
    RESOLVED = "resolved"     # 已解决
    CLOSED = "closed"        # 已关闭
    SUPPRESSED = "suppressed" # 已抑制


class AlertCategory(str, Enum):
    """告警类别枚举"""
    CROWD_SAFETY = "crowd_safety"           # 人流安全
    BEHAVIOR_SAFETY = "behavior_safety"     # 行为安全
    HYGIENE_MANAGEMENT = "hygiene_management"  # 环境卫生
    ENERGY_MANAGEMENT = "energy_management"    # 能耗管理
    CLASSROOM_QUALITY = "classroom_quality"    # 课堂质量
    TEACHING_QUALITY = "teaching_quality"      # 教学质量
    SYSTEM_HEALTH = "system_health"            # 系统健康
    DEVICE_STATUS = "device_status"            # 设备状态


class NotificationChannel(str, Enum):
    """通知渠道枚举"""
    EMAIL = "email"           # 邮件
    SMS = "sms"              # 短信
    WEBSOCKET = "websocket"   # WebSocket推送
    WEBHOOK = "webhook"       # Webhook
    MOBILE_PUSH = "mobile_push"  # 移动推送


class RuleConditionOperator(str, Enum):
    """规则条件操作符枚举"""
    EQUALS = "equals"                    # 等于
    NOT_EQUALS = "not_equals"           # 不等于
    GREATER_THAN = "greater_than"       # 大于
    LESS_THAN = "less_than"            # 小于
    GREATER_EQUAL = "greater_equal"     # 大于等于
    LESS_EQUAL = "less_equal"          # 小于等于
    CONTAINS = "contains"               # 包含
    NOT_CONTAINS = "not_contains"       # 不包含
    IN = "in"                          # 在列表中
    NOT_IN = "not_in"                  # 不在列表中


class AlertRuleCondition(BaseModel):
    """告警规则条件"""
    field: str = Field(..., description="字段名")
    operator: RuleConditionOperator = Field(..., description="操作符")
    value: Union[str, int, float, List[Any]] = Field(..., description="比较值")
    description: Optional[str] = Field(None, description="条件描述")


class AlertRuleAction(BaseModel):
    """告警规则动作"""
    action_type: str = Field(..., description="动作类型")
    parameters: Dict[str, Any] = Field(default_factory=dict, description="动作参数")
    delay_seconds: int = Field(default=0, description="延迟执行秒数")


class AlertRule(BaseModel):
    """告警规则"""
    rule_id: str = Field(..., description="规则ID")
    name: str = Field(..., description="规则名称")
    description: Optional[str] = Field(None, description="规则描述")
    category: AlertCategory = Field(..., description="告警类别")
    level: AlertLevel = Field(..., description="告警级别")
    conditions: List[AlertRuleCondition] = Field(..., description="触发条件")
    actions: List[AlertRuleAction] = Field(default_factory=list, description="执行动作")
    enabled: bool = Field(default=True, description="是否启用")
    cooldown_seconds: int = Field(default=300, description="冷却时间(秒)")
    max_alerts_per_hour: int = Field(default=10, description="每小时最大告警数")
    tags: List[str] = Field(default_factory=list, description="标签")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
    updated_at: datetime = Field(default_factory=datetime.now, description="更新时间")


class AlertEvent(BaseModel):
    """告警事件"""
    alert_id: str = Field(..., description="告警ID")
    rule_id: str = Field(..., description="规则ID")
    title: str = Field(..., description="告警标题")
    message: str = Field(..., description="告警消息")
    category: AlertCategory = Field(..., description="告警类别")
    level: AlertLevel = Field(..., description="告警级别")
    status: AlertStatus = Field(default=AlertStatus.ACTIVE, description="告警状态")
    source_data: Dict[str, Any] = Field(default_factory=dict, description="源数据")
    location: Optional[str] = Field(None, description="位置信息")
    camera_id: Optional[str] = Field(None, description="摄像头ID")
    classroom_id: Optional[str] = Field(None, description="教室ID")
    teacher_id: Optional[str] = Field(None, description="教师ID")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="元数据")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
    acknowledged_at: Optional[datetime] = Field(None, description="确认时间")
    resolved_at: Optional[datetime] = Field(None, description="解决时间")
    closed_at: Optional[datetime] = Field(None, description="关闭时间")
    assigned_to: Optional[str] = Field(None, description="分配给")
    tags: List[str] = Field(default_factory=list, description="标签")


class NotificationTemplate(BaseModel):
    """通知模板"""
    template_id: str = Field(..., description="模板ID")
    name: str = Field(..., description="模板名称")
    channel: NotificationChannel = Field(..., description="通知渠道")
    subject_template: str = Field(..., description="主题模板")
    body_template: str = Field(..., description="内容模板")
    variables: List[str] = Field(default_factory=list, description="模板变量")
    enabled: bool = Field(default=True, description="是否启用")


class NotificationConfig(BaseModel):
    """通知配置"""
    config_id: str = Field(..., description="配置ID")
    name: str = Field(..., description="配置名称")
    channels: List[NotificationChannel] = Field(..., description="通知渠道")
    recipients: List[str] = Field(..., description="接收者列表")
    alert_levels: List[AlertLevel] = Field(..., description="告警级别过滤")
    alert_categories: List[AlertCategory] = Field(..., description="告警类别过滤")
    time_windows: List[Dict[str, str]] = Field(default_factory=list, description="时间窗口")
    template_mapping: Dict[str, str] = Field(default_factory=dict, description="模板映射")
    enabled: bool = Field(default=True, description="是否启用")


class AlertNotification(BaseModel):
    """告警通知"""
    notification_id: str = Field(..., description="通知ID")
    alert_id: str = Field(..., description="告警ID")
    channel: NotificationChannel = Field(..., description="通知渠道")
    recipient: str = Field(..., description="接收者")
    subject: str = Field(..., description="通知主题")
    content: str = Field(..., description="通知内容")
    status: str = Field(default="pending", description="发送状态")
    sent_at: Optional[datetime] = Field(None, description="发送时间")
    delivered_at: Optional[datetime] = Field(None, description="送达时间")
    error_message: Optional[str] = Field(None, description="错误信息")
    retry_count: int = Field(default=0, description="重试次数")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")


class AlertStatistics(BaseModel):
    """告警统计"""
    total_alerts: int = Field(default=0, description="总告警数")
    active_alerts: int = Field(default=0, description="活跃告警数")
    resolved_alerts: int = Field(default=0, description="已解决告警数")
    alerts_by_level: Dict[str, int] = Field(default_factory=dict, description="按级别统计")
    alerts_by_category: Dict[str, int] = Field(default_factory=dict, description="按类别统计")
    alerts_by_hour: Dict[str, int] = Field(default_factory=dict, description="按小时统计")
    avg_resolution_time: float = Field(default=0.0, description="平均解决时间(分钟)")
    top_alert_sources: List[Dict[str, Any]] = Field(default_factory=list, description="主要告警源")


class AlertQuery(BaseModel):
    """告警查询条件"""
    alert_ids: Optional[List[str]] = Field(None, description="告警ID列表")
    rule_ids: Optional[List[str]] = Field(None, description="规则ID列表")
    categories: Optional[List[AlertCategory]] = Field(None, description="告警类别")
    levels: Optional[List[AlertLevel]] = Field(None, description="告警级别")
    statuses: Optional[List[AlertStatus]] = Field(None, description="告警状态")
    location: Optional[str] = Field(None, description="位置")
    camera_id: Optional[str] = Field(None, description="摄像头ID")
    classroom_id: Optional[str] = Field(None, description="教室ID")
    teacher_id: Optional[str] = Field(None, description="教师ID")
    assigned_to: Optional[str] = Field(None, description="分配给")
    tags: Optional[List[str]] = Field(None, description="标签")
    start_time: Optional[datetime] = Field(None, description="开始时间")
    end_time: Optional[datetime] = Field(None, description="结束时间")
    limit: int = Field(default=100, description="返回数量限制")
    offset: int = Field(default=0, description="偏移量")


class AlertRuleCreateRequest(BaseModel):
    """创建告警规则请求"""
    name: str = Field(..., description="规则名称")
    description: Optional[str] = Field(None, description="规则描述")
    category: AlertCategory = Field(..., description="告警类别")
    level: AlertLevel = Field(..., description="告警级别")
    conditions: List[AlertRuleCondition] = Field(..., description="触发条件")
    actions: List[AlertRuleAction] = Field(default_factory=list, description="执行动作")
    cooldown_seconds: int = Field(default=300, description="冷却时间(秒)")
    max_alerts_per_hour: int = Field(default=10, description="每小时最大告警数")
    tags: List[str] = Field(default_factory=list, description="标签")


class AlertRuleUpdateRequest(BaseModel):
    """更新告警规则请求"""
    name: Optional[str] = Field(None, description="规则名称")
    description: Optional[str] = Field(None, description="规则描述")
    category: Optional[AlertCategory] = Field(None, description="告警类别")
    level: Optional[AlertLevel] = Field(None, description="告警级别")
    conditions: Optional[List[AlertRuleCondition]] = Field(None, description="触发条件")
    actions: Optional[List[AlertRuleAction]] = Field(None, description="执行动作")
    enabled: Optional[bool] = Field(None, description="是否启用")
    cooldown_seconds: Optional[int] = Field(None, description="冷却时间(秒)")
    max_alerts_per_hour: Optional[int] = Field(None, description="每小时最大告警数")
    tags: Optional[List[str]] = Field(None, description="标签")


class AlertEventUpdateRequest(BaseModel):
    """更新告警事件请求"""
    status: Optional[AlertStatus] = Field(None, description="告警状态")
    assigned_to: Optional[str] = Field(None, description="分配给")
    tags: Optional[List[str]] = Field(None, description="标签")
    resolution_note: Optional[str] = Field(None, description="解决备注")


class AlertResponse(BaseModel):
    """告警响应"""
    success: bool = Field(..., description="是否成功")
    message: str = Field(..., description="响应消息")
    data: Optional[Any] = Field(None, description="响应数据")
    error_code: Optional[str] = Field(None, description="错误代码")